// NB: ALL NOTES DEFINED WITH STANDARD ENGLISH NAMES, EXCEPT FROM "A" 
//THAT IS CALLED WITH THE ITALIAN NAME "LA" BECAUSE A0,A1...ARE THE ANALOG PINS ON ARDUINO.
// (Ab IS CALLED Ab AND NOT LAb)
#define	C0 16.35
#define	Db0	17.32
#define	D0	18.35
#define	Eb0	19.45
#define	E0	20.60
#define	F0	21.83
#define	Gb0	23.12
#define	G0	24.50
#define	Ab0	25.96
#define	LA0	27.50
#define	Bb0	29.14
#define	B0	30.87
#define	C1	32.70
#define	Db1	34.65
#define	D1	36.71
#define	Eb1	38.89
#define	E1	41.20
#define	F1	43.65
#define	Gb1	46.25
#define	G1	49.00
#define	Ab1	51.91
#define	LA1	55.00
#define	Bb1	58.27
#define	B1	61.74
#define	C2	65.41
#define	Db2	69.30
#define	D2	73.42
#define	Eb2	77.78
#define	E2	82.41
#define	F2	87.31
#define	Gb2	92.50
#define	G2	98.00
#define	Ab2	103.83
#define	LA2	110.00
#define	Bb2	116.54
#define	B2	123.47
#define	C3	130.81
#define	Db3	138.59
#define	D3	146.83
#define	Eb3	155.56
#define	E3	164.81
#define	F3	174.61
#define	Gb3	185.00
#define	G3	196.00
#define	Ab3	207.65
#define	LA3	220.00
#define	Bb3	233.08
#define	B3	246.94
#define	C4	261.63
#define	Db4	277.18
#define	D4	293.66
#define	Eb4	311.13
#define	E4	329.63
#define	F4	349.23
#define	Gb4	369.99
#define	G4	392.00
#define	Ab4	415.30
#define	LA4	440.00
#define	Bb4	466.16
#define	B4	493.88
#define	C5	523.25
#define	Db5	554.37
#define	D5	587.33
#define	Eb5	622.25
#define	E5	659.26
#define	F5	698.46
#define	Gb5	739.99
#define	G5	783.99
#define	Ab5	830.61
#define	LA5	880.00
#define	Bb5	932.33
#define	B5	987.77
#define	C6	1046.50
#define	Db6	1108.73
#define	D6	1174.66
#define	Eb6	1244.51
#define	E6	1318.51
#define	F6	1396.91
#define	Gb6	1479.98
#define	G6	1567.98
#define	Ab6	1661.22
#define	LA6	1760.00
#define	Bb6	1864.66
#define	B6	1975.53
#define	C7	2093.00
#define	Db7	2217.46
#define	D7	2349.32
#define	Eb7	2489.02
#define	E7	2637.02
#define	F7	2793.83
#define	Gb7	2959.96
#define	G7	3135.96
#define	Ab7	3322.44
#define	LA7	3520.01
#define	Bb7	3729.31
#define	B7	3951.07
#define	C8	4186.01
#define	Db8	4434.92
#define	D8	4698.64
#define	Eb8	4978.03
// DURATION OF THE NOTES 
#define BPM 100    //  you can change this value changing all the others
#define H 2*Q //half 2/4
#define Q 60000/BPM //quarter 1/4 
#define E Q/2   //eighth 1/8
#define S Q/4 // sixteenth 1/16
#define W 4*Q // whole 4/4

const int MAX_ITERATIONS = 10;
const int FADE_DELAY = 15;
const int FADE_STEP = 1;
const int BLUE_PIN = 9;
const int GREEN_PIN = 10;
const int RED_PIN = 11;
const int BUZZER_PIN = 5;

boolean colors[3];
int lastColorIndex;
const int BLUE_POS = 0;
const int GREEN_POS = 1;
const int RED_POS = 2;

int iterations = 0;
boolean isPlaying = true;


void setup() 
{
  pinMode(RED_PIN, OUTPUT);
  pinMode(GREEN_PIN, OUTPUT);
  pinMode(BLUE_PIN, OUTPUT);
  Serial.begin(9600);
  randomSeed(millis());
  resetAllLights();
  
  music();
  
}

void loop() 
{
  if(!isPlaying)
  {
    iterations = 0;
    isPlaying = checkStart();
    randomSeed(millis());
    delay(500);
    
    randomColor();
    
  }
  else
  {
    
    
    if(iterations>=MAX_ITERATIONS)
    {
      isPlaying=false;
      fadeAllOut();
      resetAllLights();
    }
    else
    {
      int index = lastColorIndex;
      while(index==lastColorIndex)
      {
        index = random(3);        
      }
      lastColorIndex = index;
      
      colors[index] = !colors[index];
      int pin;
      if(index==RED_POS) pin=RED_PIN; 
      else if(index==GREEN_POS) pin=GREEN_PIN;
      else if(index==BLUE_POS) pin=BLUE_PIN;
      else pin=RED_PIN;

      if(colors[RED_POS]) Serial.print("RED ");
      if(colors[GREEN_POS]) Serial.print("GREEN ");
      if(colors[BLUE_POS]) Serial.print("BLUE ");
      Serial.println("");  
      fadeLight(pin, colors[index]);

      iterations++;
    }    
  }
}

boolean checkStart()
{
  return false;
}

void fadeAllOut()
{
    for(int fadeValue = 254 ; fadeValue >= 0; fadeValue -=FADE_STEP) 
    {
      if(colors[RED_POS]) analogWrite(RED_PIN, fadeValue);
      if(colors[GREEN_POS]) analogWrite(GREEN_PIN, fadeValue);
      if(colors[BLUE_POS]) analogWrite(BLUE_PIN, fadeValue);
      delay(FADE_DELAY);
    }  
}

void resetAllLights()
{
  analogWrite(GREEN_PIN, 0);
  analogWrite(BLUE_PIN, 0);
  analogWrite(RED_PIN, 0);
  
  lastColorIndex = GREEN_POS;
  colors[BLUE_POS] = false;
  colors[GREEN_POS] = false;
  colors[RED_POS] = false;
}

void randomColor()
{
  analogWrite(GREEN_PIN, random(255));
  analogWrite(BLUE_PIN, random(255));
  analogWrite(RED_PIN, random(255));
}

void fadeLight(int pin, boolean up)
{
  if(up)
  {
    for(int fadeValue = 0 ; fadeValue <=254; fadeValue +=FADE_STEP)
    {
      analogWrite(pin, fadeValue);
      delay(FADE_DELAY);
    }
  }
  else
  {
    for(int fadeValue = 254 ; fadeValue >= 0; fadeValue -=FADE_STEP) 
    {
      analogWrite(pin, fadeValue);
      delay(FADE_DELAY);
    }
  } 
}

void mtone(unsigned int frequency, unsigned long duration)
{
  randomColor();
  tone(BUZZER_PIN, frequency, duration);
  delay(1+duration); //delay duration should always be 1 ms more than the note in order to separate them.
}

void mpause(unsigned long duration)
{
  delay(1+duration); 
  analogWrite(GREEN_PIN, 0);
  analogWrite(BLUE_PIN, 0);
  analogWrite(RED_PIN, 0);  
}

void music()
{
  
    mtone(C5,E);
    mtone(C5,Q);
    mtone(D5,E);
    mtone(C5,Q);
    mtone(B4,E);
    mtone(B4,E);
    mtone(LA3,Q);
    mtone(LA3,E);
    mpause(E);
    mtone(E3,E);
    mtone(F3,E);
    mtone(G3,E);
    mtone(G4,E);
    mtone(F4,E);
    mtone(B3,Q);
    mtone(LA3,Q);
        
  //DO DO RE DO SI SI LA SOL LA SI DO DOSI LA SOL;
  
 
     
}
